# encoding=utf-8
from selenium import webdriver
import time
import random
from utils import DbUtil
import uuid
from selenium.webdriver import ActionChains
from PIL import Image as Im
import os
import cv2
import numpy as np
import requests
from pymongo import MongoClient


# 图片下载到本地,返回一个本地链接。url 是图片的链接,type区分左侧小拼图和大图,
# 大图传big,小图传small
def pic_download(url,type):
    url = url
    root = "D:/emils_python/pic_test/"
    # path = root + str(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()))+'.png'
    path = root + type + '.png'
    try:
        if not os.path.exists(root):
            os.mkdir(root)
        if os.path.exists(path):
            os.remove(path)
        r = requests.get(url)
        r.raise_for_status()
        # 使用with语句可以不用自己手动关闭已经打开的文件流
        with open(path, "wb") as f:  # 开始写文件，wb代表写二进制文件
            f.write(r.content)
            print(f.name)
        print("下载完成")
        return f.name

    except Exception as e:
        print("获取失败!" + str(e))


# 获取缺口位置 small_url是小图的路径(本地),big_url是大图的路径(本地) 最后return一个计算出的距离
def get_distance(small_url, big_url):
    # 引用上面的图片下载
    otemp = pic_download(small_url, 'small')

    time.sleep(2)

    # 引用上面的图片下载
    oblk = pic_download(big_url, 'big')

    # 计算拼图还原距离
    target = cv2.imread(otemp, 0)
    template = cv2.imread(oblk, 0)
    w, h = target.shape[::-1]
    temp = 'temp.jpg'
    targ = 'targ.jpg'
    cv2.imwrite(temp, template)
    cv2.imwrite(targ, target)
    target = cv2.imread(targ)
    target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
    target = abs(255 - target)
    cv2.imwrite(targ, target)
    target = cv2.imread(targ)
    template = cv2.imread(temp)
    result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
    x, y = np.unravel_index(result.argmax(), result.shape)
    # 缺口位置
    print((y, x, y + w, x + h))

    # 调用PIL Image 做测试
    image = Im.open(oblk)

    xy = (y + 20, x + 20, y + w - 20, x + h - 20)
    # 切割
    imagecrop = image.crop(xy)
    # 保存切割的缺口
    imagecrop.save("D:/emils_python/pic_test/new_image.jpg")
    return y
if __name__=='__main__':
    try:
        # 先切换frame回到默认
        browser.switch_to.default_content()

        # 将frame切换到 login_frame(也就是之前的登录frame)
        browser.switch_to.frame("login_frame")

        # 根据xpath获取到含有安全提示的标签然后将其中文本获取到打印出来 如果异常就进except块 说明没有验证码
        code = browser.find_element_by_xpath('//*[@id="newVcodeArea"]/div[1]/div/div[2]').text
        print(code)

        # 如果后面拖动失败 我们就再次循环 所以用while
        while True:
            # 切换frame
            browser.switch_to.default_content()

            # 切换frame
            browser.switch_to.frame('login_frame')

            # 切换带有刷新按钮的frame
            browser.switch_to.frame(browser.find_element_by_xpath('//*[@id="newVcodeIframe"]/iframe'))

            # 点击刷新 id为e_reload
            browser.find_element_by_id('e_reload').click()

            # 获取图片链接
            big_url = browser.find_element_by_id('slideBkg').get_attribute('src')
            small_url = browser.find_element_by_id('slideBlock').get_attribute('src')

            # 下载图片并计算拼图还原的距离
            y = get_distance(small_url, big_url)

        # 获取当前网页链接，用于判断拖动验证码后是否成功,如果拖动后地址没变则为失败
        url1 = browser.current_url

        # 获取蓝色拖动按钮对象
        element = browser.find_element_by_id('tcaptcha_drag_button')

        # 计算distance
        #按钮需要滑动的距离（网页） =
        # 拼图的还原距离（本地图片） * (网页上的长度 / 本地图片的长度) -21(多出来的起始位置)
        distance = y * (280 / 680) - 21
        print('distance:', distance)
        # 模拟人为拖动按钮
        has_gone_dist = 0
        remaining_dist = distance
        # distance += randint(-10, 10)
        # 按下鼠标左键
        ActionChains(browser).click_and_hold(element).perform()
        time.sleep(0.5)
        while remaining_dist > 0:
            ratio = remaining_dist / distance
            if ratio < 0.2:
                # 开始阶段移动较慢
                span = random.randint(5, 8)
            elif ratio > 0.8:
                # 结束阶段移动较慢
                span = random.randint(5, 8)
            else:
                # 中间部分移动快
                span = random.randint(10, 16)
        ActionChains(browser).move_by_offset(span, random.randint(-5, 5)).perform()
        remaining_dist -= span
        has_gone_dist += span
        time.sleep(random.randint(5, 20) / 100)

        ActionChains(browser).move_by_offset(remaining_dist, random.randint(-5, 5)).perform()
        ActionChains(browser).release(on_element=element).perform()
    except:
        print('无安全验证码!')


